﻿using mozhi.smarterp.Business.Products.Repositories;
using mozhi.smarterp.Business.Products.Services;
using Mozhi.Abp.Domain.BasicData;
using Mozhi.Abp.Domain.BasicData.Repositories;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;

namespace mozhi.smarterp.Business.Products
{
    public class ProductPurchaseSettingAppService : BusinessAppService, IProductPurchaseSettingAppService
    {
        private IProductPurchaseSettingRepository _repository;
        private ProductPurchaseSettingManager _manager;
        private IProductRepository _productRepository;
        private IUnitRepository _unitRepository;
        private ISupplierRepository _supplierRepository;
        private IEmployeeRepository _employeeRepository;


        public ProductPurchaseSettingAppService(IProductPurchaseSettingRepository repository, ProductPurchaseSettingManager manager, IProductRepository productRepository, 
            IUnitRepository unitRepository, ISupplierRepository supplierRepository, IEmployeeRepository employeeRepository)
        {
            _repository = repository;
            _manager = manager;
            _productRepository = productRepository;
            _unitRepository = unitRepository;
            _supplierRepository = supplierRepository;
            _employeeRepository = employeeRepository;
        }

        public async Task<ProductPurchaseSettingDto> CreateAsync(ProductPurchaseSettingCreateDto input)
        {
            var purchaseSetting = await _manager.GetAsync(null, input.ProductId, input.PurchaseUnitId.Value, input.DefaultSupplierId.Value, input.DefaultPurchaserId, input.MinPurchaseQuantity);

            purchaseSetting = await _repository.InsertAsync(purchaseSetting);

            var result = ObjectMapper.Map<ProductPurchaseSetting, ProductPurchaseSettingDto>(purchaseSetting);

            await LoadOtherInfoAsync(new List<ProductPurchaseSettingDto> { result });

            return result;
        }

        public async Task DeleteAsync(Guid productId)
        {
            var setting = await _repository.GetByProductIdAsync(productId);

            if (setting == null)
                return;

            await _repository.DeleteAsync(setting.Id);
        }

        public async Task<ProductPurchaseSettingDto> GetAsync(Guid productId)
        {
            var purchaseSetting = await _repository.GetByProductIdAsync(productId);

            var result = ObjectMapper.Map<ProductPurchaseSetting, ProductPurchaseSettingDto>(purchaseSetting);

            if (result == null)
                return result;

            await LoadOtherInfoAsync(new List<ProductPurchaseSettingDto> { result });

            return result;
        }

        public async Task<PagedResultDto<ProductPurchaseSettingDto>> GetListAsync(PagedAndSortedResultRequestDto filter)
        {
            var purchaseSettings = await _repository.GetPagedListAsync(filter.SkipCount, filter.MaxResultCount, filter.Sorting);

            var count = await _repository.GetCountAsync();

            var items = ObjectMapper.Map<List<ProductPurchaseSetting>, List<ProductPurchaseSettingDto>>(purchaseSettings);

            await LoadOtherInfoAsync(items);

            return new PagedResultDto<ProductPurchaseSettingDto>()
            {
                Items = items,
                TotalCount = count
            };
        }

        public async Task<ProductPurchaseSettingDto> UpdateAsync(ProductPurchaseSettingUpdateDto input)
        {
            var purchaseSetting = await _manager.GetAsync(input.Id, input.ProductId, input.PurchaseUnitId.Value, input.DefaultSupplierId.Value, input.DefaultPurchaserId, input.MinPurchaseQuantity);

            purchaseSetting = await _repository.UpdateAsync(purchaseSetting);

            var result = ObjectMapper.Map<ProductPurchaseSetting, ProductPurchaseSettingDto>(purchaseSetting);

            await LoadOtherInfoAsync(new List<ProductPurchaseSettingDto> { result });

            return result;
        }

        #region
        private async Task LoadOtherInfoAsync(List<ProductPurchaseSettingDto> purchaseSettings)
        {
            if (purchaseSettings == null)
                return;

            foreach (var purchaseSetting in purchaseSettings)
            {
                var product = await _productRepository.GetAsync(purchaseSetting.ProductId);

                purchaseSetting.ProductCode = product?.Code;
                purchaseSetting.ProductName = product?.Name;

                var unit = await _unitRepository.GetAsync(purchaseSetting.PurchaseUnitId);

                purchaseSetting.PurchaseUnitName = unit?.Name;

                var supplier = await _supplierRepository.GetAsync(purchaseSetting.DefaultSupplierId);

                purchaseSetting.DefaultSupplierName = supplier?.Name;

                var purchaser = await _employeeRepository.GetAsync(purchaseSetting.DefaultPurchaserId);

                purchaseSetting.DefaultPurchaserName = purchaser?.Name;

            }
        }
        #endregion
    }
}
